package cn.bon.emp.service.impl;

import cn.bon.common.exception.BizIllegalException;
import cn.bon.emp.api.pojo.po.EmpOrg;
import cn.bon.emp.api.pojo.po.Org;
import cn.bon.emp.api.pojo.vo.OrgVO;
import cn.bon.emp.api.enums.OrgLevel;

import cn.bon.emp.mapper.OrgMapper;
import cn.bon.emp.service.IEmpOrgService;
import cn.bon.emp.service.IOrgService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织架构 服务实现类
 * </p>
 *
 * @author luochao
 * @since 2023-12-09
 */
@Service
public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org> implements IOrgService {
    @Resource
    OrgMapper orgMapper;

    @Resource
    IEmpOrgService empOrgService;

    /**
     * 查询所有分组
     * @return
     */
    @Override
    public List<OrgVO> getAll() {
        return getWithParent(0l);
    }

    /**
     * 查询指定节点下的子节点
     * @param parentId
     * @return
     */
    public List<OrgVO> getWithParent(Long parentId) {
        //查询对应班组
        List<OrgVO> orgVOs = orgMapper.listWithParent(parentId);
        for (OrgVO orgVO : orgVOs) {
            if (orgVO.getOrgLevel()==OrgLevel.ORG_GROUP) continue;
            List<OrgVO> children = getWithParent(orgVO.getOrgId());
            orgVO.setChildren(children);
        }
        return orgVOs;
    }


    /**
     * 添加子节点
     *
     * @param org
     * @return
     */
    @Override
    public OrgVO add(Org org) {
        Org father = orgMapper.getById(org.getParentId());
        if (father == null) throw new BizIllegalException("父节点不存在");

        switch (father.getOrgLevel()) {
            case ORG_COMPANY -> org.setOrgLevel(OrgLevel.ORG_DEPT).setParentId(0l);
            case ORG_DEPT -> org.setOrgLevel(OrgLevel.ORG_SECTION);
            case ORG_SECTION -> org.setOrgLevel(OrgLevel.ORG_GROUP);
            case ORG_GROUP -> throw new BizIllegalException("小组为最低组织级别，不能添加子节点");
        }

        try {   //避免用一组下班组名重复
            orgMapper.save(org);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) throw new BizIllegalException("该班组已存在");
        }
        return orgMapper.getById2Vo(org.getOrgId());
    }

    /**
     * 修改节点
     *
     * @param org
     */
    @Override
    public OrgVO edit(Org org) {
        Org oldOne = orgMapper.getById(org.getOrgId());
        if (oldOne == null) throw new BizIllegalException("用户不存在或者已删除");
        OrgLevel orgLevel = oldOne.getOrgLevel();
        if (orgLevel==OrgLevel.ORG_COMPANY||orgLevel==OrgLevel.ORG_DEPT)
            throw new BizIllegalException("部门以上级别不支持修改");
        BeanUtil.copyProperties(org,oldOne, CopyOptions.create().setIgnoreNullValue(true));
        orgMapper.updateByID(oldOne);
        return orgMapper.getById2Vo(oldOne.getOrgId());
    }

    /**
     * 删除指定org
     *
     * @param id
     */
    @Override
    @Transactional
    public void delete(Long id) {
        Org org = orgMapper.getById(id);
        if (org == null) throw new BizIllegalException("班组不存在");
        OrgLevel orgLevel = org.getOrgLevel();
        if (orgLevel==OrgLevel.ORG_COMPANY||orgLevel==OrgLevel.ORG_DEPT)
            throw new BizIllegalException("部门以上级别不支持删除");

        if (orgLevel == OrgLevel.ORG_SECTION) //科室级别 删除子小组
            orgMapper.rmByParentId(id);

        //重置对应组织的人员
        empOrgService.rmOfOrg(id);

        //删除对应组织
        orgMapper.rmById(id);
    }
}
